home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / human interface toolbox / fragment tool / dialogstuff.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  22.2 KB  |  793 lines

  1. /*
  2.     File:        DialogStuff.c
  3.  
  4.     Contains:    Handle application's dialogs
  5.  
  6.     Written by: Chris White    
  7.  
  8.     Copyright:    Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved.
  9.  
  10.                 You may incorporate this Apple sample source code into your program(s) without
  11.                 restriction. This Apple sample source code has been provided "AS IS" and the
  12.                 responsibility for its operation is yours. You are not permitted to redistribute
  13.                 this Apple sample source code as "Apple sample source code" after having made
  14.                 changes. If you're going to re-distribute the source, we require that you make
  15.                 it clear in the source that the code was descended from Apple sample source
  16.                 code, but that you've made changes.
  17.  
  18.     Change History (most recent first):
  19.                 8/5/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  20.                 
  21.  
  22. */
  23.  
  24. #include <Types.h>
  25. #include <Quickdraw.h>
  26. #include <QDOffscreen.h>
  27. #include <Devices.h>
  28. #include <LowMem.h>
  29. #include <TextUtils.h>
  30. #include <Dialogs.h>
  31. //#include <stddef.h>
  32. #include <CodeFragments.h>
  33. #include <StandardFile.h>
  34. #include <Folders.h>
  35.  
  36. #include "FragmentTool.h"
  37. #include "FragmentStuff.h"
  38. #include "DialogStuff.h"
  39. #include "Streams.h"
  40. #include "Utilities.h"
  41. #include "Prototypes.h"
  42.  
  43. static OSErr CreateContentList ( WindowRef theWindow, tContentsProcPtr contentsProc, void* refCon );
  44. static void AddContentsToList ( WindowRef theWindow );
  45. static int8 GetStageFromItem ( int16 theItem );
  46. static int16 GetItemFromStage ( int8 theStage );
  47. void GetNameFromDialog ( DialogRef theDialog, StringPtr theName );
  48.  
  49.  
  50.  
  51.  
  52.  
  53. //
  54. // Creates a simple dialog with a single list. A routine pointer is passed
  55. // as an argument which add the list contents.
  56. //
  57. OSErr CreateListDialog ( DialogRef* dialogRef, int16 dialogID, StringPtr dialogTitle,
  58.                             tContentsProcPtr contentsProc, void* refCon )
  59. {
  60.     int16            theType;
  61.     OSErr            theErr;
  62.     GrafPtr            savePort;
  63.     DialogRef        theDialog = nil;
  64.     ListRef            theList = nil;
  65.     Handle            theHandle;
  66.     Point            cellSize = {0, 0};
  67.     Cell            firstCell = {0, 0};
  68.     Rect            dataRect = {0, 0, 0, 1};
  69.     Rect            theRect;
  70.     
  71.     
  72.     
  73.     theDialog = GetNewDialog ( dialogID, nil, (WindowRef) -1L );
  74.     if ( theDialog == nil )
  75.         return kGenericError;
  76.     
  77.     // Creates the data structure assigned to the window's refCon field
  78.     theErr = CreateWindowInfo ( theDialog, sizeof ( tDialogInfo ) );
  79.     if ( theErr )
  80.     {
  81.         // Don't forget to free any storage we've used so far
  82.         DestroyDialog ( theDialog );
  83.         return theErr;
  84.     }
  85.     
  86.     GetPort ( &savePort );
  87.     SetPortWindowPort ( theDialog );
  88.     TextFont ( kFontIDGeneva );
  89.     TextFace ( normal );
  90.     TextSize ( 9 );
  91.     
  92.     SetWindowType ( theDialog, kListWindowType );
  93.     SetWTitle ( theDialog, dialogTitle );
  94.     
  95.     GetDialogItem ( theDialog, kListUserItem, &theType, &theHandle, &theRect );
  96.     SetDialogItem ( theDialog, kListUserItem, theType, (Handle) gOutlineUserItemUPP, &theRect );
  97.     
  98.     theRect.right -= 15;
  99.     theList = LNew ( &theRect, &dataRect, cellSize, 0, theDialog, 
  100.                         false, false, false, true );
  101.     if ( theList )
  102.     {
  103.         tDialogInfoPtr    theInfo;
  104.         
  105.         theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  106.         theInfo->listRef = theList;
  107.         (*theList)->selFlags = lOnlyOne;
  108.         
  109.         // Since the calling routine is always in the same architecture type as
  110.         // the callback routine, we don't need to worry about any Mixed Mode
  111.         // complications. We just treat it as a straight forward routine pointer.
  112.         
  113.         theErr = (*contentsProc) ( theList, refCon );
  114.         if ( theErr )
  115.         {
  116.             // Don't forget to free any storage we've used so far
  117.             DestroyDialog ( theDialog );
  118.             SetPort ( savePort );
  119.             return theErr;
  120.         }
  121.         
  122.         LSetSelect ( true, firstCell, theList );
  123.  
  124.         // Now the list has been fully prepared, turn the drawing mode on. This
  125.         // isn't srictly necessary since the window isn't supposed to visible.
  126.         LSetDrawingMode ( true, theList );
  127.     }
  128.     
  129.     SetPort ( savePort );
  130.     
  131.     SelectWindow ( theDialog );
  132.     ShowWindow ( theDialog );
  133.  
  134.     *dialogRef = theDialog;
  135.     
  136.     return noErr;
  137. }
  138.  
  139.  
  140.  
  141. //
  142. // Creates the dialog used for the GetInfo command. Displays information about
  143. // the code fragment. This is the stuff contained within the 'cfrg' resource
  144. //
  145. OSErr CreateInfoDialog ( DialogRef* dialogRef, StringPtr dialogTitle, WindowRef theWindow, int16 theIndex )
  146. {
  147.     OSErr            theErr;
  148.     GrafPtr            savePort = nil;
  149.     DialogRef        theDialog = nil;
  150.     TEHandle        textH;
  151.     tDialogInfoPtr    theInfo;
  152.     tStreamRef        theStream = nil;
  153.     tItemPtr        theItem;
  154.     FontInfo        theFontInfo;
  155.  
  156.     
  157.     theDialog = GetNewDialog ( 2002, nil, (WindowRef) -1L );
  158.     if ( theDialog == nil )
  159.         return kGenericError;
  160.     
  161.     theErr = CreateWindowInfo ( theDialog, sizeof ( tDialogInfo ) );
  162.     if ( theErr )
  163.         goto CleanupAndBail;
  164.     
  165.     GetPort ( &savePort );
  166.     SetPortWindowPort ( theDialog );
  167.     TextFont ( kFontIDGeneva );
  168.     TextFace ( normal );
  169.     TextSize ( 9 );
  170.     
  171.     // We're using a different font than the standard, so we need to
  172.     // change the fields in the textedit record. Otherwise, any text
  173.     // that is being edited will be display in the standard font.
  174.     GetFontInfo ( &theFontInfo );
  175.     textH = ((DialogPeek) theDialog)->textH;
  176.     (*textH)->txFont = kFontIDGeneva;
  177.     (*textH)->txFace = normal;
  178.     (*textH)->txSize = 9;
  179.     (*textH)->lineHeight = theFontInfo.ascent + theFontInfo.descent + theFontInfo.leading;
  180.     (*textH)->fontAscent = theFontInfo.ascent;
  181.     
  182.     SetWindowType ( theDialog, kGetInfoWindowType );
  183.     SetWTitle ( theDialog, dialogTitle );
  184.     
  185.     
  186.     // The window is needed to make the document dirty if the user makes
  187.     // a change. The item points to the information displayed in the dialog.
  188.     
  189.     theErr = NewStream ( &theStream, sizeof ( WindowRef ) + sizeof ( int16 ) );
  190.     if ( theErr ) goto CleanupAndBail;
  191.     
  192.     theErr = SetStreamData ( theStream, (Ptr) &theWindow, sizeof ( WindowRef ) );
  193.     if ( theErr ) goto CleanupAndBail;
  194.     
  195.     theErr = SetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  196.     if ( theErr ) goto CleanupAndBail;
  197.  
  198.     theErr = CompactStream ( theStream );
  199.     if ( theErr ) goto CleanupAndBail;
  200.     
  201.     theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  202.     theInfo->refCon = (int32) theStream;
  203.     
  204.     // Set up the dialog with the information from the selected item 
  205.     theItem = GetNthWindowItem ( theWindow, theIndex );
  206.     theErr = SetDialogValues ( theDialog, theItem );
  207.     if ( theErr ) goto CleanupAndBail;
  208.     
  209.     SetPort ( savePort );
  210.     
  211.     SelectWindow ( theDialog );
  212.     ShowWindow ( theDialog );
  213.     
  214.     *dialogRef = theDialog;
  215.     
  216.     return noErr;
  217.     
  218. CleanupAndBail:
  219.     // Don't forget to free any storage we've used so far. goto's are very useful
  220.     // for things like error recovery. That's how many of the exception stack
  221.     // implementations work in class frameworks.
  222.     
  223.     if ( theStream )
  224.         DisposeStream ( theStream );
  225.     if ( theDialog )
  226.         DestroyDialog ( theDialog );
  227.     if ( savePort )
  228.         SetPort ( savePort );
  229.         
  230.     return theErr;
  231. }
  232.  
  233.  
  234.  
  235. //
  236. // Our one-fits-all routine to free up everything
  237. // to do with a  dialog.
  238. //
  239. DialogRef DestroyDialog ( DialogRef theDialog )
  240. {
  241.     if ( theDialog )
  242.     {
  243.         tDialogInfoPtr    theInfo;
  244.         
  245.         theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  246.         if ( theInfo )
  247.         {
  248.             if ( theInfo->listRef )
  249.                 LDispose ( theInfo->listRef );
  250.             DisposePtr ( (Ptr) theInfo );
  251.         }
  252.         
  253.         DisposeDialog ( theDialog );
  254.     }
  255.     
  256.     // We'll return nil so the result can assigned to
  257.     // the dialog reference that was passed in.
  258.     return nil;
  259. }
  260.  
  261.  
  262.  
  263. //
  264. // This routine's pointer is passed into CreateListDialog
  265. // to add the contents to a newly created list.
  266. //
  267. OSErr AddFragmentExports ( ListRef theList, void* refCon )
  268. {
  269.     int                        i;
  270.     int32                    theCount;
  271.     OSErr                    theErr = noErr;
  272.     CFragLoadOptions        theFlags = kLoadCFrag;
  273.     tItemPtr                theItem;
  274.     Ptr                        mainAddr, symAddr;
  275.     CFragConnectionID        theConnID;
  276.     CFragSymbolClass        symClass;
  277.     tAddFragmentExportsRec*    theRec;
  278.     Str255                    symName;
  279.     static Str255            errName;
  280.     
  281.     
  282.     theRec = (tAddFragmentExportsRec*) refCon;
  283.     theItem = theRec->u.out.theItem;
  284.     if ( theItem == nil )
  285.         return kGenericError;
  286.     
  287.     
  288.     // Since 'errName' must be valid after the routine has
  289.     // gone out of scope, the variable is declaired static.
  290.     
  291.     
  292.     // The fragment may not exist in the document yet. If this is the
  293.     // case, we'll need to get the fragment from the temporary file. 
  294.     if ( theItem->bExistsInDocument )
  295.         theErr = GetDiskFragment ( theRec->u.out.theSpecPtr, theItem->codeOffset, theItem->codeLength,
  296.                                     theItem->name, theFlags, &theConnID, &mainAddr, errName );
  297.     else
  298.         theErr = GetDiskFragment ( GetTempSpecPtr ( theItem ), 0, 0, theItem->name, theFlags, &theConnID, &mainAddr, errName );
  299.     
  300.     if ( theErr )
  301.     {
  302.         theRec->bIn = true;
  303.         theRec->u.in.theErrorStr = errName;
  304.         return theErr;
  305.     }
  306.     
  307.     theErr = CountSymbols ( theConnID, &theCount );
  308.     if ( theErr ) goto CleanupAndBail;
  309.     
  310.     for ( i = 0; i < theCount; i++ )
  311.     {
  312.         theErr = GetIndSymbol ( theConnID, i, symName, &symAddr, &symClass );
  313.         if ( theErr ) goto CleanupAndBail;
  314.         
  315.         AddToList ( theList, symName );
  316.     }
  317.     
  318.     
  319. CleanupAndBail:
  320.     
  321.     CloseConnection ( &theConnID );
  322.     
  323.     return theErr;
  324. }
  325.  
  326.  
  327.  
  328. //
  329. // This routine's pointer is passed into CreateListDialog
  330. // to add the names of each document, except the front-most.
  331. //
  332. OSErr AddDocuments ( ListRef theList, void* refCon )
  333. {
  334.     #pragma unused(refCon)
  335.     int            theIndex = 0;
  336.     WindowRef    theWindow;
  337.     
  338.     
  339.     
  340.     // By structuring the routines this way, we can ensure that the index we
  341.     // retrive from the List Manager (as the selected item) can be passed into
  342.     // the GetIndexedDocumentWindow routine to get the correct window. This
  343.     // minimizes any logical dependencies between different routines. Most
  344.     // of the logic is contained within the GetIndexedDocumentWindow routine.
  345.     
  346.     while ( 0 != (theWindow = GetIndexedDocumentWindow(theIndex++)))
  347.     {
  348.         Str255    theText;
  349.         
  350.         GetWTitle ( theWindow, theText );
  351.         AddToList ( theList, theText );
  352.     }
  353.     
  354.     return noErr;
  355. }
  356.  
  357.  
  358.  
  359. // This routine is called to setup all the dialog items with the information
  360. // from a fragment. We pass in a pointer to its data structure.
  361. OSErr SetDialogValues ( DialogRef theDialog, tItemPtr theItem )
  362. {
  363.     int16    itemType;
  364.     int16    tmpNum;
  365.     Handle    theHandle;
  366.     Rect    theRect;
  367.     Str255    tmpString = "\p";
  368.     
  369.     // Name of the fragment
  370.     GetDialogItem ( theDialog, kNameEditText, &itemType, &theHandle, &theRect );
  371.     SetDialogItemText ( theHandle, theItem->name );
  372.     
  373.     // The fragment's arichtecture. For example, m68k
  374.     GetDialogItem ( theDialog, kArchitectureStaticText, &itemType, &theHandle, &theRect );
  375.     OSTypeToPStr ( theItem->archType, tmpString );
  376.     SetDialogItemText ( theHandle, tmpString );
  377.     
  378.     // The update level. We use a popup menu for this information
  379.     GetDialogItem ( theDialog, kUpdateLevelPopup, &itemType, &theHandle, &theRect );
  380.     SetControlValue ( (ControlHandle) theHandle, theItem->updateLevel + 1 );
  381.     
  382.     // Current Version
  383.     GetDialogItem ( theDialog, kCurrentMajorEditText, &itemType, &theHandle, &theRect );
  384.     NumToString ( (*(NumVersion*)&theItem->currVersion).majorRev, tmpString );
  385.     SetDialogItemText ( theHandle, tmpString );
  386.     
  387.     GetDialogItem ( theDialog, kCurrentMinorEditText, &itemType, &theHandle, &theRect );
  388.     NumToString ( (*(NumVersion*)&theItem->currVersion).minorAndBugRev & 0xF0, tmpString );
  389.     SetDialogItemText ( theHandle, tmpString );
  390.     
  391.     GetDialogItem ( theDialog, kCurrentBugRevEditText, &itemType, &theHandle, &theRect );
  392.     NumToString ( (*(NumVersion*)&theItem->currVersion).minorAndBugRev & 0x0F, tmpString );
  393.     SetDialogItemText ( theHandle, tmpString );
  394.     
  395.     GetDialogItem ( theDialog, kCurrentStagePopup, &itemType, &theHandle, &theRect );
  396.     tmpNum = GetItemFromStage ( (*(NumVersion*)&theItem->currVersion).stage );
  397.     SetControlValue ( (ControlHandle) theHandle, tmpNum );
  398.  
  399.     GetDialogItem ( theDialog, kCurrentNonRelEditText, &itemType, &theHandle, &theRect );
  400.     NumToString ( (*(NumVersion*)&theItem->currVersion).nonRelRev, tmpString );
  401.     SetDialogItemText ( theHandle, tmpString );
  402.     
  403.     // Old Version
  404.     GetDialogItem ( theDialog, kOldMajorEditText, &itemType, &theHandle, &theRect );
  405.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).majorRev, tmpString );
  406.     SetDialogItemText ( theHandle, tmpString );
  407.     
  408.     GetDialogItem ( theDialog, kOldMinorEditText, &itemType, &theHandle, &theRect );
  409.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev & 0xF0, tmpString );
  410.     SetDialogItemText ( theHandle, tmpString );
  411.     
  412.     GetDialogItem ( theDialog, kOldBugRevEditText, &itemType, &theHandle, &theRect );
  413.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev & 0x0F, tmpString );
  414.     SetDialogItemText ( theHandle, tmpString );
  415.     
  416.     GetDialogItem ( theDialog, kOldStagePopup, &itemType, &theHandle, &theRect );
  417.     tmpNum = GetItemFromStage ( (*(NumVersion*)&theItem->oldDefVersion).stage );
  418.     SetControlValue ( (ControlHandle) theHandle, tmpNum );
  419.     
  420.     GetDialogItem ( theDialog, kOldNonRelEditText, &itemType, &theHandle, &theRect );
  421.     NumToString ( (*(NumVersion*)&theItem->oldDefVersion).nonRelRev, tmpString );
  422.     SetDialogItemText ( theHandle, tmpString );
  423.     
  424.     // Stack size. Only relevant if this thing's an application
  425.     GetDialogItem ( theDialog, kStackSizeEditText, &itemType, &theHandle, &theRect );
  426.     NumToString ( theItem->appStackSize / 1024, tmpString );
  427.     SetDialogItemText ( theHandle, tmpString );
  428.     
  429.     // Resource ID of an alias record to look for fragments. We don't do much with this.
  430.     GetDialogItem ( theDialog, kSubFolderIDEditText, &itemType, &theHandle, &theRect );
  431.     NumToString ( theItem->appStackSize, tmpString );
  432.     SetDialogItemText ( theHandle, tmpString );
  433.     
  434.     // Usage. Is this an application, library, or what.
  435.     GetDialogItem ( theDialog, kUsagePopup, &itemType, &theHandle, &theRect );
  436.     SetControlValue ( (ControlHandle) theHandle, theItem->usage + 1 );
  437.     
  438.     // This is currently "hard-coded" in the dialog resource. We'll leave it alone.
  439.     GetDialogItem ( theDialog, kLocationStaticText, &itemType, &theHandle, &theRect );
  440.     // NumToString ( theItem->location, tmpString );
  441.     // SetDialogItemText ( theHandle, tmpString );
  442.     
  443.     // Offset to the fragment in the data fork.
  444.     if ( theItem->bExistsInDocument ) // Has it been saved? We don't know the offset otherwise
  445.     {
  446.         GetDialogItem ( theDialog, kOffsetStaticText, &itemType, &theHandle, &theRect );
  447.         NumToString ( theItem->codeOffset, tmpString );
  448.         SetDialogItemText ( theHandle, tmpString );
  449.     }
  450.     
  451.     // Length of the fragment in the data fork
  452.     GetDialogItem ( theDialog, kLengthStaticText, &itemType, &theHandle, &theRect );
  453.     NumToString ( theItem->codeLength, tmpString );
  454.     SetDialogItemText ( theHandle, tmpString );
  455.     
  456.     return noErr;
  457. }
  458.  
  459.  
  460.  
  461. //
  462. // The opposite of the above routine. This one gets the values from the dialog
  463. // fields and puts them in the fragment's data structure
  464. //
  465. OSErr GetDialogValues ( DialogRef theDialog, tItemPtr theItem )
  466. {
  467.     int16    itemType;
  468.     int32    tmpNum;
  469.     Handle    theHandle;
  470.     Rect    theRect;
  471.     Str255    tmpString = "\p";
  472.     
  473.  
  474.  
  475.     // Name of the fragment
  476.     GetDialogItem ( theDialog, kNameEditText, &itemType, &theHandle, &theRect );
  477.     GetDialogItemText ( theHandle, theItem->name );
  478.     
  479.     // The update level. We use a popup menu for this information
  480.     GetDialogItem ( theDialog, kUpdateLevelPopup, &itemType, &theHandle, &theRect );
  481.     theItem->updateLevel = GetControlValue ( (ControlHandle) theHandle ) - 1;
  482.     
  483.     // Current Version
  484.     GetDialogItem ( theDialog, kCurrentMajorEditText, &itemType, &theHandle, &theRect );
  485.     GetDialogItemText ( theHandle, tmpString );
  486.     StringToNum ( tmpString, &tmpNum );
  487.     (*(NumVersion*)&theItem->currVersion).majorRev = tmpNum;
  488.     
  489.     GetDialogItem ( theDialog, kCurrentMinorEditText, &itemType, &theHandle, &theRect );
  490.     GetDialogItemText ( theHandle, tmpString );
  491.     StringToNum ( tmpString, &tmpNum );
  492.     (*(NumVersion*)&theItem->currVersion).minorAndBugRev = tmpNum << 4;
  493.     
  494.     GetDialogItem ( theDialog, kCurrentBugRevEditText, &itemType, &theHandle, &theRect );
  495.     GetDialogItemText ( theHandle, tmpString );
  496.     StringToNum ( tmpString, &tmpNum );
  497.     (*(NumVersion*)&theItem->currVersion).minorAndBugRev += tmpNum;
  498.     
  499.     GetDialogItem ( theDialog, kCurrentStagePopup, &itemType, &theHandle, &theRect );
  500.     tmpNum = GetControlValue ( (ControlHandle) theHandle );
  501.     (*(NumVersion*)&theItem->currVersion).stage = GetStageFromItem ( tmpNum );
  502.     
  503.     GetDialogItem ( theDialog, kCurrentNonRelEditText, &itemType, &theHandle, &theRect );
  504.     GetDialogItemText ( theHandle, tmpString );
  505.     StringToNum ( tmpString, &tmpNum );
  506.     (*(NumVersion*)&theItem->currVersion).nonRelRev = tmpNum;
  507.     
  508.     // Old Version
  509.     GetDialogItem ( theDialog, kOldMajorEditText, &itemType, &theHandle, &theRect );
  510.     GetDialogItemText ( theHandle, tmpString );
  511.     StringToNum ( tmpString, &tmpNum );
  512.     (*(NumVersion*)&theItem->oldDefVersion).majorRev = tmpNum;
  513.     
  514.     GetDialogItem ( theDialog, kOldMinorEditText, &itemType, &theHandle, &theRect );
  515.     GetDialogItemText ( theHandle, tmpString );
  516.     StringToNum ( tmpString, &tmpNum );
  517.     (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev = tmpNum << 4;
  518.     
  519.     GetDialogItem ( theDialog, kOldBugRevEditText, &itemType, &theHandle, &theRect );
  520.     GetDialogItemText ( theHandle, tmpString );
  521.     StringToNum ( tmpString, &tmpNum );
  522.     (*(NumVersion*)&theItem->oldDefVersion).minorAndBugRev += tmpNum;
  523.     
  524.     GetDialogItem ( theDialog, kOldStagePopup, &itemType, &theHandle, &theRect );
  525.     tmpNum = GetControlValue ( (ControlHandle) theHandle );
  526.     (*(NumVersion*)&theItem->oldDefVersion).stage = GetStageFromItem ( tmpNum );
  527.     
  528.     GetDialogItem ( theDialog, kOldNonRelEditText, &itemType, &theHandle, &theRect );
  529.     GetDialogItemText ( theHandle, tmpString );
  530.     StringToNum ( tmpString, &tmpNum );
  531.     (*(NumVersion*)&theItem->oldDefVersion).nonRelRev = tmpNum;
  532.     
  533.     // Stack size. Only relevant if this thing's an application
  534.     GetDialogItem ( theDialog, kStackSizeEditText, &itemType, &theHandle, &theRect );
  535.     GetDialogItemText ( theHandle, tmpString );
  536.     StringToNum ( tmpString, &theItem->appStackSize );
  537.     
  538.     // Resource ID of an alias record to look for fragments. We don't do much with this.
  539.     GetDialogItem ( theDialog, kSubFolderIDEditText, &itemType, &theHandle, &theRect );
  540.     GetDialogItemText ( theHandle, tmpString );
  541.     StringToNum ( tmpString, &theItem->appStackSize );
  542.     
  543.     // Usage. Is this an application, library, or what.
  544.     GetDialogItem ( theDialog, kUsagePopup, &itemType, &theHandle, &theRect );
  545.     theItem->usage = GetControlValue ( (ControlHandle) theHandle ) - 1;
  546.     
  547.     
  548.     return noErr;
  549. }
  550.  
  551.  
  552.  
  553. void GetNameFromDialog ( DialogRef theDialog, StringPtr theName )
  554. {
  555.     int16    itemType;
  556.     Handle    theHandle;
  557.     Rect    theRect;
  558.     
  559.     // Just the name of the fragment
  560.     GetDialogItem ( theDialog, kNameEditText, &itemType, &theHandle, &theRect );
  561.     GetDialogItemText ( theHandle, theName );
  562. }
  563.  
  564.  
  565.  
  566. //
  567. // Convert between the popup item number and what it means
  568. //
  569. int8 GetStageFromItem ( int16 theItem )
  570. {
  571.     int8 theStage = 0;
  572.     
  573.     switch ( theItem )
  574.     {
  575.         case 1:
  576.             theStage = 0x20;
  577.         break;
  578.         
  579.         case 2:
  580.             theStage = 0x40;
  581.         break;
  582.         
  583.         case 3:
  584.             theStage = 0x60;
  585.         break;
  586.         
  587.         case 4:
  588.             theStage = 0x80;
  589.         break;
  590.     }
  591.     
  592.     return theStage;
  593. }
  594.  
  595.  
  596.  
  597. //
  598. // Convert between the popup item number and what it means
  599. //
  600. int16 GetItemFromStage ( int8 theStage )
  601. {
  602.     int16 theItem = 0;
  603.     
  604.     switch ( theStage )
  605.     {
  606.         case 0x20:
  607.             theItem = 1;
  608.         break;
  609.         
  610.         case 0x40:
  611.             theItem = 2;
  612.         break;
  613.         
  614.         case 0x60:
  615.             theItem = 3;
  616.         break;
  617.         
  618.         case 0x80:
  619.             theItem = 4;
  620.         break;
  621.     }
  622.     
  623.     return theItem;
  624. }
  625.  
  626.  
  627.  
  628. //
  629. // Handle a click in a dialog
  630. //
  631. void DoDialogContentClick ( DialogRef theDialog, EventRecord* theEvent )
  632. {
  633.     SInt16 itemHit;
  634.     
  635.     
  636.     SetPort ( theDialog );
  637.     
  638.     if ( DialogSelect ( theEvent, &theDialog, &itemHit ) )
  639.         DoDialogItemHit ( theDialog, itemHit );
  640.     else
  641.     {
  642.         if ( GetWindowType ( theDialog ) == kListWindowType )
  643.         {
  644.             ListRef            theList;
  645.             tDialogInfoPtr    theInfo;
  646.             Point            localPt;
  647.             
  648.             
  649.             theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  650.             theList = theInfo->listRef;
  651.             
  652.             localPt = theEvent->where;
  653.             GlobalToLocal ( &localPt );
  654.             
  655.             if ( LClick ( localPt, theEvent->modifiers, theList ) )        /* double clicked? */
  656.                 DoDialogItemHit ( theDialog, kStdOkItemIndex );
  657.         }    
  658.     }
  659.     
  660.     
  661.     return;
  662. }
  663.  
  664.  
  665.  
  666. //
  667. // Handle a dialog item hit
  668. //
  669. void DoDialogItemHit ( DialogRef theDialog, int16 theItem )
  670. {
  671.     switch ( theItem )
  672.     {
  673.         case kStdOkItemIndex:
  674.         {
  675.             int16    theSubType;
  676.             
  677.             theSubType = GetWindowSubType ( theDialog );
  678.             switch ( theSubType )
  679.             {
  680.                 case kMoveFragmentWindowSubType:
  681.                     MoveCopySelectedFragments ( theDialog, true );
  682.                 break;
  683.                 
  684.                 case kCopyFragmentWindowSubType:
  685.                     MoveCopySelectedFragments ( theDialog, false );
  686.                 break;
  687.                 
  688.                 default:
  689.                     if ( GetWindowType ( theDialog ) == kGetInfoWindowType )
  690.                     {
  691.                         tDialogInfoPtr    theInfo;
  692.                         tStreamRef        theStream;
  693.                         
  694.                         
  695.                         theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  696.                         theStream = (tStreamRef) theInfo->refCon;
  697.                         if ( theStream )
  698.                         {
  699.                             OSErr        theErr;
  700.                             int16        theIndex;
  701.                             WindowRef    theWindow;
  702.                             tItemPtr    theItem;
  703.                             Str255        theName;
  704.                             
  705.                             
  706.                             ResetStreamCursor ( theStream );
  707.                             theErr = GetStreamData ( theStream, (Ptr) &theWindow, sizeof ( WindowRef ) );
  708.                             theErr = GetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  709.                             DisposeStream ( theStream );
  710.                             
  711.                             theItem = GetNthWindowItem ( theWindow, theIndex );
  712.                             GetNameFromDialog ( theDialog, theName );
  713.                             UpdateFragInList ( theWindow, theIndex, theName );
  714.                             GetDialogValues ( theDialog, theItem );
  715.                             
  716.                             SetDocumentDirty ( theWindow, true );
  717.                         }
  718.                     }
  719.                 break;
  720.             }
  721.             DestroyDialog ( theDialog );
  722.         }
  723.         break;
  724.         
  725.         case kStdCancelItemIndex:
  726.             DestroyDialog ( theDialog );
  727.         break;
  728.     }
  729.     return;
  730.     
  731. } // DoDialogItemHit
  732.  
  733.  
  734.  
  735. //
  736. // Perform's the copy/move after the user selects a traget document
  737. // from the dialog.
  738. //
  739. void MoveCopySelectedFragments ( DialogRef theDialog, Boolean bMove )
  740. {
  741.     int16            theIndex = 0;
  742.     tDialogInfoPtr    theInfo;
  743.     
  744.     
  745.     theInfo = (tDialogInfoPtr) GetWRefCon ( theDialog );
  746.     if ( GetSelection ( theInfo->listRef, &theIndex ) )
  747.     {
  748.         OSErr            theErr;
  749.         int                theCount, i;
  750.         WindowRef        sourceWindow, targetWindow;
  751.         tStreamRef        theStream;
  752.         
  753.         
  754.         
  755.         // All the information is passed in a data stream
  756.         // built by the PackageWindowData routine. It consists of the source
  757.         // window reference, the number of fragments to copy or move, and
  758.         // then an array of index values.
  759.         
  760.         targetWindow = GetIndexedDocumentWindow ( theIndex );
  761.         if ( targetWindow == nil )
  762.         {
  763.             AlertUser ( kGenericErrorStr, 0, nil );
  764.             return;
  765.         }
  766.         
  767.         theStream = (tStreamRef) theInfo->refCon;
  768.         ResetStreamCursor ( theStream );
  769.         theErr = GetStreamData ( theStream, (Ptr) &sourceWindow, sizeof ( WindowRef ) );
  770.         theErr = GetStreamData ( theStream, (Ptr) &theCount, sizeof ( int ) );
  771.         
  772.         for ( i = 0; i < theCount; i++ )
  773.         {
  774.             theErr = GetStreamData ( theStream, (Ptr) &theIndex, sizeof ( int16 ) );
  775.             if ( bMove )
  776.                 theErr = MoveWindowFragment ( sourceWindow, theIndex, targetWindow );
  777.             else
  778.                 theErr = CopyWindowFragment ( sourceWindow, theIndex, targetWindow );
  779.         }
  780.         
  781.         DisposeStream ( theStream );
  782.         
  783.     }
  784.     
  785.     return;
  786. }
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.